/********************************************
 * 功能说明: 
 * 模块名称: 
 * 系统名称: 
 * 软件版权: 
 * 系统版本: 1.0.0
 * 开发人员: zhangfb
 * 开发时间: 2019/4/9 18:06
 * 审核人员: 
 * 相关文档: 
 * 修改记录: 修改日期 修改人员 修改说明
 *********************************************/
package com.hyacinth.activity.service;

import com.hyacinth.activity.domain.ActDict;
import com.hyacinth.activity.domain.ActRequest;
import com.hyacinth.activity.domain.ActResponse;
import com.hyacinth.activity.entity.ActivityPlan;
import com.hyacinth.activity.entity.User;
import com.hyacinth.activity.utils.SpringBeanFactory;
import com.hyacinth.service.BaseService;
import com.hyacinth.utils.DateUtils;
import com.hyacinth.wapper.RetValue;

import java.util.Date;

/**
 * 活动方案服务抽象类
 * @author zhangfb
 * @version 1.0.0.1
 * @since JDK 1.8
 */
public abstract class ActivityPlanService extends BaseService {

    /**
     * 活动触法
     * @param actRequest 活动请求信息
     * @return 响应结果
     */
    public final ActResponse triggerActivity(ActRequest actRequest) {
        // 1.校验活动是否合法
        RetValue ret = checkAct(actRequest);
        if (!ret.isSuccess()) {
            return ActResponse.failure(ret.getMessage());
        }
        // 2.校验商户是否满足参加活动条件
        ret = checkShop(actRequest);
        if (!ret.isSuccess()) {
            return ActResponse.failure(ret.getMessage());
        }
        // 3.校验用户是否满足参加活动条件
        ret = checkActUser(actRequest);
        if (!ret.isSuccess()) {
            return ActResponse.failure(ret.getMessage());
        }
        // 4.执行活动规则
        return executeActivity(actRequest);
    }

    private RetValue checkAct(ActRequest actRequest) {
        // 1.活动通用校验
        RetValue ret = checkComm(actRequest);
        if (!ret.isSuccess()) {
            return ret;
        }
        // 2.活动自校验
        ret = checkActivity(actRequest);
        if (!ret.isSuccess()) {
            return ret;
        }
        return RetValue.getSuccessReturnValue();
    }

    /**
     * 活动公共有效性校验
     */
    private RetValue checkComm(ActRequest actRequest) {
        ActivityPlan plan = actRequest.getPlan();
        if (plan == null) {
            return RetValue.getErrorReturnValue("活动方案为空");
        }
        // 1.校验活动状态
        if (!ActDict.activityPlanStatus_02.equals(plan.getStatus())) {
            return RetValue.getErrorReturnValue("活动状态异常");
        }
        // 2.校验活动是否开始
        Date today = new Date();
        if (today.before(plan.getBegTime())) {
            return RetValue.getErrorReturnValue("活动未开始");
        }
        // 3.校验活动是否结束
        if (today.after(plan.getEndTime())) {
            // 活动过期，需要更新活动状态为已过期
            expiredActivity(plan);
            return RetValue.getErrorReturnValue("活动已结束");
        }
        // 4.校验到日是否是活动日
        if (!plan.getDaysOfWeek().contains("" + DateUtils.getDayOfWeek())) {
            return RetValue.getErrorReturnValue("今天不是活动日");
        }
        return RetValue.getSuccessReturnValue();
    }

    /**
     * 校验商户是否满足活动条件
     * @param actRequest 活动请求信息
     * @return 校验结果
     */
    private RetValue checkActUser(ActRequest actRequest) {
        // 1.校验必要参数
        User user = actRequest.getUser();
        if (user == null) {
            return RetValue.getErrorReturnValue("参与活动用户信息为空");
        }
        // 2.活动用户校验
        RetValue ret = checkUser(actRequest);
        if (!ret.isSuccess()) {
            return ret;
        }
        // 3.校验用户参与次数
        PartiActRecordService partiActRecordService = SpringBeanFactory.getBean(PartiActRecordService.class);
        ret = partiActRecordService.checkPartiTimes(actRequest.getPlan(), user.getCode());
        if (!ret.isSuccess()) {
            return ret;
        }
        return RetValue.getSuccessReturnValue();
    }

    /**
     * 执行活动规则
     * @param actRequest 活动请求信息
     * @return 响应结果
     */
    protected abstract ActResponse executeActivity(ActRequest actRequest);

    /**
     * 校验活动合法性
     * @param actRequest 活动请求信息
     * @return 校验结果
     */
    protected abstract RetValue checkActivity(ActRequest actRequest);

    /**
     * 校验商户是否满足活动条件
     * @param actRequest 活动请求信息
     * @return 校验结果
     */
    protected abstract RetValue checkUser(ActRequest actRequest);

    /**
     * 校验商户是否满足活动条件
     * @param actRequest 活动请求信息
     * @return 校验结果
     */
    protected abstract RetValue checkShop(ActRequest actRequest);

    /**
     * 活动过期，需要更新活动状态为已过期
     * @param plan 活动方案
     */
    protected abstract void expiredActivity(ActivityPlan plan);
}
